package com.ssy.lingxi.contract.serviceimpl;

import com.ssy.lingxi.common.exception.BusinessException;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.contract.component.OfficeConvertService;
import com.ssy.lingxi.contract.constant.Constants;
import com.ssy.lingxi.contract.entity.ContractTemplate;
import com.ssy.lingxi.contract.entity.SignatureLog;
import com.ssy.lingxi.contract.model.bo.sign.ContractParamFillBO;
import com.ssy.lingxi.contract.model.bo.sign.ContractParamMemberFillBO;
import com.ssy.lingxi.contract.model.bo.sign.SignAuthDetailBO;
import com.ssy.lingxi.contract.model.bo.sign.SignFlowBO;
import com.ssy.lingxi.contract.model.constant.CommonBooleanEnum;
import com.ssy.lingxi.contract.model.vo.sign.request.*;
import com.ssy.lingxi.contract.model.vo.sign.response.OrderSettleSignDetailResponse;
import com.ssy.lingxi.contract.model.vo.sign.response.SignContractCreateResponse;
import com.ssy.lingxi.contract.model.vo.sign.response.SignCreateResponse;
import com.ssy.lingxi.contract.repository.ContractTemplateRepository;
import com.ssy.lingxi.contract.repository.SignatureLogRepository;
import com.ssy.lingxi.contract.service.IOrderSignatureService;
import com.ssy.lingxi.contract.service.ISignatureService;
import com.ssy.lingxi.contract.service.ISignatureUserDetailService;
import com.ssy.lingxi.contract.utils.ContractTemplateUtil;
import com.ssy.lingxi.contract.utils.FileUtils;
import com.ssy.lingxi.feign.UploadControllerFeign;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.Objects;

/**
 * 订单合同签署服务实现类
 * @author yzc
 * @version 2.0.0
 * @date 2021/1/28
 */
@Slf4j
@Service
public class OrderSignatureServiceImpl extends BaseContractSignatureService implements IOrderSignatureService {

    @Resource
    private ContractTemplateRepository contractTemplateRepository;
//    @Resource
//    private ContractParamRepository contractParamRepository;
    @Resource
    private UploadControllerFeign uploadControllerFeign;
    @Resource
    private OfficeConvertService officeConvertService;
    @Resource
    private ISignatureService signatureService;
    @Resource
    private ISignatureUserDetailService signatureUserDetailService;
    @Resource
    private SignatureLogRepository signatureLogRepository;

    @Override
    public Wrapper<SignContractCreateResponse> signContractCreate(SignContractRequest request, UserLoginCacheDTO sysUser) {
        // 甲方会员id(采购商)
        Long platformMemberId = request.getMemberId();
        // 乙方会员id(供应商)
        Long signMemberId = sysUser.getMemberId();

        // ============================甲方=============================
        // 甲方签章申请信息(主导方)
        SignAuthDetailBO leadingAuthDetail = signatureUserDetailService.getSignAuthDetail(platformMemberId);
        if (Objects.isNull(leadingAuthDetail)) {
            return Wrapper.fail(ResponseCode.CONTRACT_LEADING_NO_APPLY_SIGN_AUTH);
        }

        // 甲方认证状态
        if (!CommonBooleanEnum.YES.getCode().equals(leadingAuthDetail.getState())) {
            return Wrapper.fail(ResponseCode.CONTRACT_LEADING_NO_APPLY_SIGN_AUTH);
        }
        // 甲方合同模板填充参数
        ContractParamMemberFillBO leadingContractFillParam = this.getContractFillParam(leadingAuthDetail);


        // ============================乙方=============================
        // 乙方签章申请信息(劳务方)
        SignAuthDetailBO laborAuthDetail = signatureUserDetailService.getSignAuthDetail(signMemberId);
        if (Objects.isNull(laborAuthDetail)) {
            return Wrapper.fail(ResponseCode.CONTRACT_LABOR_NO_APPLY_SIGN_AUTH);
        }

        // 乙方认证状态
        if (!CommonBooleanEnum.YES.getCode().equals(laborAuthDetail.getState())) {
            return Wrapper.fail(ResponseCode.CONTRACT_LABOR_NO_APPLY_SIGN_AUTH);
        }

        // 乙方合同模板填充参数
        ContractParamMemberFillBO laborContractFillParam = this.getContractFillParam(laborAuthDetail);

        // 合同模板信息
        ContractTemplate contractTemplate = contractTemplateRepository.findById(request.getContractTemplateId()).orElse(null);
        if (Objects.isNull(contractTemplate)) {
            return Wrapper.fail(ResponseCode.CONTRACT_DATA_RECORDS_DOES_NOT_EXIST);
        }

        // 获取合同模板文件信息
        byte[] bytes = FileUtils.fileDownload(contractTemplate.getFileUrl());
        if (bytes.length <= 0) {
            return Wrapper.fail(ResponseCode.CONTRACT_READ_CONTRACT_FAIL);
        }

        // 填充合同参数
        ContractParamFillBO paramFillBO = ContractParamFillBO.build();
        paramFillBO.setLeadingContractFillParam(leadingContractFillParam);
        paramFillBO.setLaborContractFillParam(laborContractFillParam);

//        // 查询订单信息
//        ContractOrderDetailsRequest contractOrderDetailsRequest = new ContractOrderDetailsRequest();
//        contractOrderDetailsRequest.setOrderId(request.getOrderId());
//        contractOrderDetailsRequest.setSysUser(sysUser);
//        Wrapper<ProcurementOrderDetailsResponse> orderDetails = purchaseOrderControllerFeign.getOrderDetails(contractOrderDetailsRequest);
//        if (ResponseCode.SUCCESS.getCode() != orderDetails.getCode()) {
//            return Wrapper.fail(ResponseCode.SERVICE_ORDER_ERROR);
//        }
//
//        // 订单参数
//        this.fillContractParam(paramFillBO, orderDetails.getData());

        byte[] docBytes = ContractTemplateUtil.fillContractTemplate(bytes, paramFillBO);
        if (Objects.isNull(docBytes)) {
            return Wrapper.fail(ResponseCode.CONTRACT_FILL_CONTRACT_FAIL);
        }

        // word转pdf
        byte[] pdfBytes;
        try {
            // 转换
            ByteArrayInputStream docbais = new ByteArrayInputStream(docBytes);
            ByteArrayOutputStream pdfbaos = new ByteArrayOutputStream();
            officeConvertService.convert(docbais, pdfbaos, Constants.contract_file_doc_suffix, Constants.contract_file_pdf_suffix);

            pdfBytes = pdfbaos.toByteArray();
        } catch (Exception e) {
            log.error("word转pdf", e);
            return Wrapper.fail(ResponseCode.CONTRACT_WORD_TO_PDF_FAIL);
        }

        // 上传到oss
        MultipartFile multipartFile = FileUtils.createMultipartFile(pdfBytes, Constants.contract_file_pdf_suffix);
        if (Objects.isNull(multipartFile)) {
            return Wrapper.fail(ResponseCode.FILE_UPLOAD_ERROR);
        }
        Wrapper<String> uploadResponse = uploadControllerFeign.upload(multipartFile);
        if (ResponseCode.SUCCESS.getCode() != uploadResponse.getCode()) {
            return Wrapper.fail(uploadResponse.getCode(), uploadResponse.getMessage());
        }

        // 返回结果
        SignContractCreateResponse response = new SignContractCreateResponse();
        // 供应商公司名 + 合同名称 + 订单编号
        String contractNameSb = laborContractFillParam.getOrgName() +
                contractTemplate.getName() +
                ".pdf";
        response.setContractName(contractNameSb);
        response.setContractUrl(uploadResponse.getData());
        return Wrapper.success(response);
    }

    @Override
    public Wrapper<SignContractCreateResponse> preOrderSignContractCreate(SignContractPreOrderRequest request, UserLoginCacheDTO sysUser) {
        // 甲方会员id(采购商)
        Long platformMemberId = sysUser.getMemberId();
        // 乙方会员id(供应商)
        Long signMemberId = request.getMemberId();

        // ============================甲方=============================
        // 甲方签章申请信息(主导方)
        SignAuthDetailBO leadingAuthDetail = signatureUserDetailService.getSignAuthDetail(platformMemberId);
        if (Objects.isNull(leadingAuthDetail)) {
            return Wrapper.fail(ResponseCode.CONTRACT_LEADING_NO_APPLY_SIGN_AUTH);
        }

        // 甲方认证状态
        if (!CommonBooleanEnum.YES.getCode().equals(leadingAuthDetail.getState())) {
            return Wrapper.fail(ResponseCode.CONTRACT_LEADING_NO_APPLY_SIGN_AUTH);
        }
        // 甲方合同模板填充参数
        ContractParamMemberFillBO leadingContractFillParam = this.getContractFillParam(leadingAuthDetail);


        // ============================乙方=============================
        // 乙方签章申请信息(劳务方)
        SignAuthDetailBO laborAuthDetail = signatureUserDetailService.getSignAuthDetail(signMemberId);
        if (Objects.isNull(laborAuthDetail)) {
            return Wrapper.fail(ResponseCode.CONTRACT_LABOR_NO_APPLY_SIGN_AUTH);
        }

        // 乙方认证状态
        if (!CommonBooleanEnum.YES.getCode().equals(laborAuthDetail.getState())) {
            return Wrapper.fail(ResponseCode.CONTRACT_LABOR_NO_APPLY_SIGN_AUTH);
        }

        // 乙方合同模板填充参数
        ContractParamMemberFillBO laborContractFillParam = this.getContractFillParam(laborAuthDetail);

        // 合同模板信息
        ContractTemplate contractTemplate = contractTemplateRepository.findById(request.getContractTemplateId()).orElse(null);
        if (Objects.isNull(contractTemplate)) {
            return Wrapper.fail(ResponseCode.CONTRACT_DATA_RECORDS_DOES_NOT_EXIST);
        }

        // 获取合同模板文件信息
        byte[] bytes = FileUtils.fileDownload(contractTemplate.getFileUrl());
        if (bytes.length <= 0) {
            return Wrapper.fail(ResponseCode.CONTRACT_READ_CONTRACT_FAIL);
        }

        // 计算订单金额和运费
//        CountOrderPriceRequest countOrderPriceRequest = new CountOrderPriceRequest();
//        countOrderPriceRequest.setQuotationNo(request.getQuotationNo());
//        countOrderPriceRequest.setOrderProductRequests(request.getOrderProductRequests());
//        countOrderPriceRequest.setDeliveryAddresId(request.getDeliveryAddresId());
//        Wrapper<CountOrderPriceResponse> countOrderPriceResponseWrapper = purchaseOrderControllerFeign.countOrderPrice(countOrderPriceRequest);
//        if (ResponseCode.SUCCESS.getCode() != countOrderPriceResponseWrapper.getCode()) {
//            return Wrapper.fail(ResponseCode.SERVICE_ORDER_ERROR);
//        }
//        BigDecimal freightPrice = BigDecimal.valueOf(countOrderPriceResponseWrapper.getData().getTotalPrice());
//        BigDecimal totalPrice = BigDecimal.valueOf(countOrderPriceResponseWrapper.getData().getFreightPrice());

        // 填充合同参数
        ContractParamFillBO paramFillBO = ContractParamFillBO.build();
        paramFillBO.setLeadingContractFillParam(leadingContractFillParam);
        paramFillBO.setLaborContractFillParam(laborContractFillParam);

//        // 订单参数
//        this.fillContractParamPreOrder(paramFillBO, request.getOrderProductRequests(), freightPrice, totalPrice);

        byte[] docBytes = ContractTemplateUtil.fillContractTemplate(bytes, paramFillBO);
        if (Objects.isNull(docBytes)) {
            return Wrapper.fail(ResponseCode.CONTRACT_FILL_CONTRACT_FAIL);
        }

        // word转pdf
        byte[] pdfBytes;
        try {
            // 转换
            ByteArrayInputStream docbais = new ByteArrayInputStream(docBytes);
            ByteArrayOutputStream pdfbaos = new ByteArrayOutputStream();
            officeConvertService.convert(docbais, pdfbaos, Constants.contract_file_doc_suffix, Constants.contract_file_pdf_suffix);

            pdfBytes = pdfbaos.toByteArray();
        } catch (Exception e) {
            log.error("word转pdf", e);
            return Wrapper.fail(ResponseCode.CONTRACT_WORD_TO_PDF_FAIL);
        }

        // 上传到oss
        MultipartFile multipartFile = FileUtils.createMultipartFile(pdfBytes, Constants.contract_file_pdf_suffix);
        if (Objects.isNull(multipartFile)) {
            return Wrapper.fail(ResponseCode.FILE_UPLOAD_ERROR);
        }
        Wrapper<String> uploadResponse = uploadControllerFeign.upload(multipartFile);
        if (ResponseCode.SUCCESS.getCode() != uploadResponse.getCode()) {
            return Wrapper.fail(uploadResponse.getCode(), uploadResponse.getMessage());
        }

        // 返回结果
        SignContractCreateResponse response = new SignContractCreateResponse();
        // 供应商公司名 + 合同名称 + 订单编号
        String contractNameSb = laborContractFillParam.getOrgName() +
                contractTemplate.getName() +
                ".pdf";
        response.setContractName(contractNameSb);
        response.setContractUrl(uploadResponse.getData());
        return Wrapper.success(response);
    }

    @Override
    public Wrapper<SignCreateResponse> saleSign(PlatformSignRequest request, UserLoginCacheDTO sysUser) {
        Long firstMemberId = request.getMemberId();
        Long secondMemberId = sysUser.getMemberId();

        // 甲方签章申请信息(主导方)
        SignAuthDetailBO leadingAuthDetail = signatureUserDetailService.getSignAuthDetail(firstMemberId);
        if (Objects.isNull(leadingAuthDetail)) {
            return Wrapper.fail(ResponseCode.CONTRACT_LEADING_NO_APPLY_SIGN_AUTH);
        }

        // 甲方认证状态
        if (!CommonBooleanEnum.YES.getCode().equals(leadingAuthDetail.getState())) {
            return Wrapper.fail(ResponseCode.CONTRACT_LEADING_NO_APPLY_SIGN_AUTH);
        }

        // 乙方签章申请信息(劳务方)
        SignAuthDetailBO laborAuthDetail = signatureUserDetailService.getSignAuthDetail(secondMemberId);
        if (Objects.isNull(laborAuthDetail)) {
            return Wrapper.fail(ResponseCode.CONTRACT_LABOR_NO_APPLY_SIGN_AUTH);
        }

        // 乙方认证状态
        if (!CommonBooleanEnum.YES.getCode().equals(laborAuthDetail.getState())) {
            return Wrapper.fail(ResponseCode.CONTRACT_LABOR_NO_APPLY_SIGN_AUTH);
        }

        // 合同流程创建
        SignFlowBO signFlowBO = signatureService.signatureFlowCreate(leadingAuthDetail, laborAuthDetail, request.getContractName(), request.getContractUrl());

        // 乙方签署
        signatureService.secondSign(laborAuthDetail, signFlowBO.getSignatureLogId());

        // 数据返回
        SignCreateResponse response = new SignCreateResponse();
        response.setSignatureLogId(signFlowBO.getSignatureLogId());
        return Wrapper.success(response);
    }

    @Override
    public Wrapper<Void> procurementSign(AutoSignRequest request, UserLoginCacheDTO sysUser) {
        Long firstMemberId = sysUser.getMemberId();

        // 甲方签章申请信息(主导方)
        SignAuthDetailBO leadingAuthDetail = signatureUserDetailService.getSignAuthDetail(firstMemberId);
        if (Objects.isNull(leadingAuthDetail)) {
            return Wrapper.fail(ResponseCode.CONTRACT_LEADING_NO_APPLY_SIGN_AUTH);
        }

        // 甲方认证状态
        if (!CommonBooleanEnum.YES.getCode().equals(leadingAuthDetail.getState())) {
            return Wrapper.fail(ResponseCode.CONTRACT_LEADING_NO_APPLY_SIGN_AUTH);
        }

        // 甲方签署
        signatureService.firstSign(leadingAuthDetail, request.getSignatureLogId());

        // 签署流程开启
        signatureService.signStart(request.getSignatureLogId());

        return Wrapper.success();
    }

    @Override
    public Wrapper<SignCreateResponse> settlementOrderSettleSign(OrderSettleSignRequest request, UserLoginCacheDTO sysUser) {
        // 合同模板信息
        ContractTemplate contractTemplate = contractTemplateRepository.findById(request.getContractTemplateId()).orElse(null);
        if (Objects.isNull(contractTemplate)) {
            throw new BusinessException(ResponseCode.CONTRACT_DATA_RECORDS_DOES_NOT_EXIST);
        }

        Long firstMemberId = sysUser.getMemberId();
        Long secondMemberId = contractTemplate.getMemberId();

        // 甲方签章申请信息(主导方)
        SignAuthDetailBO leadingAuthDetail = signatureUserDetailService.getSignAuthDetail(firstMemberId);
        if (Objects.isNull(leadingAuthDetail)) {
            return Wrapper.fail(ResponseCode.CONTRACT_LEADING_NO_APPLY_SIGN_AUTH);
        }

        // 甲方认证状态
        if (!CommonBooleanEnum.YES.getCode().equals(leadingAuthDetail.getState())) {
            return Wrapper.fail(ResponseCode.CONTRACT_LEADING_NO_APPLY_SIGN_AUTH);
        }

        // 乙方签章申请信息(劳务方)
        SignAuthDetailBO laborAuthDetail = signatureUserDetailService.getSignAuthDetail(secondMemberId);
        if (Objects.isNull(laborAuthDetail)) {
            return Wrapper.fail(ResponseCode.CONTRACT_LABOR_NO_APPLY_SIGN_AUTH);
        }

        // 乙方认证状态
        if (!CommonBooleanEnum.YES.getCode().equals(laborAuthDetail.getState())) {
            return Wrapper.fail(ResponseCode.CONTRACT_LABOR_NO_APPLY_SIGN_AUTH);
        }

        Long signatureLogId = signatureService.oneStepSign(leadingAuthDetail, laborAuthDetail, request.getContractName(), request.getContractUrl());

        SignCreateResponse response = new SignCreateResponse();
        response.setSignatureLogId(signatureLogId);

        return Wrapper.success(response);
    }

    @Override
    public Wrapper<OrderSettleSignDetailResponse> orderSettleSignDetail(OrderSettleSignDetailRequest request) {
        SignatureLog signatureLog = signatureLogRepository.findById(request.getSignatureLogId()).orElse(null);
        if (Objects.isNull(signatureLog)) {
            return Wrapper.fail(ResponseCode.CONTRACT_DATA_RECORDS_DOES_NOT_EXIST);
        }

        OrderSettleSignDetailResponse response = new OrderSettleSignDetailResponse();
        response.setState(signatureLog.getState());
        response.setContractUrl(signatureLog.getFileUrl());
        return Wrapper.success(response);
    }
}